import s94 from 's94-js';
import s94_rem from './s94_rem.mjs.js'

var s94_app = (function(global){
    "use strict";
    var is_bower = /^http/.test(global.location.href);
    if (is_bower) return {};
    s94(function (){
        s94.load.status = false;
        let old_os = s94.load.os;
        setTimeout(()=>{
            s94.load.init(old_os);
        },200)
    })
    Object.defineProperty(global, 'apiready', {
        value: function(){
            let map = {
                'android': s94.OS_APP_ANDROID,
                'ios': s94.OS_APP_IOS,
                'wp': s94.OS_APP_WP
            }
            s94.load.status = false;
            s94.load.init(map[api.systemType] || s94.OS_APP_OTHER);
            app_init();
            console.log('is_app');
        }
    })
    function app_init(){
        document.documentElement.style.setProperty('--safe-area-top', (api.safeArea.top / s94_rem.scale)+'px');
        document.documentElement.style.setProperty('--safe-area-bottom', (api.safeArea.bottom / s94_rem.scale)+'px');
        api.setStatusBarStyle({style: 'dark'});
    }

    function _app(name){
        return api.require(name);
    }
    _app.ajax = s94.unifyRequest({
        reqData(setup){
            return new Promise(function (resolve){
                if(!setup.data) resolve(setup);
                if (setup.type == 'JSONP' || setup.type == 'GET') {
                    setup.url += (setup.url.indexOf('?') == -1?'?':'&') + s94.param_encode(setup.data);
                    setup.data = null;
                    resolve(setup);
                }else{
                    setup.cache = false; //存在POST数据的情况下，始终不使用缓存，
                    if (setup.data instanceof _app.ajaxData){
                        delete setup.contentType;
                        resolve(setup);
                    }else if (setup.data instanceof FormData){
                        setup.contentType = 'application/x-www-form-urlencoded';
                        let thenable = Promise.resolve(), arr=[];
                        for(let pair of setup.data.entries()) {
                            thenable = thenable.then(function(){
                                if(pair[1] instanceof Blob){
                                    return new Promise((ok)=>{
                                        var r = new FileReader();
                                        r.onload = function(){
                                            arr.push(encodeURIComponent(pair[0]) + '=' + encodeURIComponent(r.result));
                                            ok(arr);
                                        }
                                        r.readAsDataURL(pair[1]);
                                    })
                                }else{
                                    arr.push(encodeURIComponent(pair[0]) + '=' + encodeURIComponent(pair[1]) );
                                    return arr;
                                }
                            })
                        }
                        thenable.then(function(){
                            setup.data = arr.join('&');
                            resolve(setup)
                        })
                    }else {
                        if (setup.data instanceof URLSearchParams) setup.data = setup.data.toString();
                        switch (setup.contentType) {
                            case 'application/json':{
                                if (typeof(setup.data) == 'object') setup.data = JSON.stringify(setup.data);
                            }break;
                            default:{
                                setup.contentType = 'application/x-www-form-urlencoded';
                                if (typeof(setup.data) == 'object') setup.data = s94.param_encode(setup.data);
                            }
                        }
                        if (typeof(setup.data) != 'string') setup.data += '';
                        resolve(setup);
                    }
                }
            })
        },
        send(setup){
            var _this = this;
            if(!(setup.data instanceof _app.ajaxData)) setup.data = {body: setup.data}
            setup.method = setup.method.toLowerCase();
            setup.returnAll = true;
            setup.report = typeof(setup.progress) == 'function';
            setup.dataType = 'text';
            if (setup.contentType) setup.headers["Content-Type"] = setup.contentType;
            api.ajax(setup, function (ret, err) {
                setup.ret = ret;
                setup.err = err;
                if (ret && ret.status==0) return _this.callback(setup, 'progress');
                if (ret) {
                    setup.response.code = ret.statusCode;
                    setup.response.headers = ret.headers || {};
                    s94.each(setup.response.headers, function(v,k){
                        setup.response.headers[k.toLowerCase()] = v;
                    })
                    setup.response.body = ret.body;
                } else {
                    setup.response.code = err.statusCode;
                    setup.response.body = err.body || err.msg;
                }
                _this.resData(setup);
                if (setup.response.code >= 200 && setup.response.code < 400) {
                    _this.callback(setup, 'success');
                }else{
                    _this.callback(setup, 'error');
                }
                _this.callback(setup, 'complete');
            });
        }
    })

    //永久Storage引擎
    _app.localStorage = {
        getItem: function(name){
            return api.getPrefs({sync: true,key: name});
        },
        setItem: function(name, value){
            return api.setPrefs({key: name,value: value});
        },
        removeItem: function(name){
            return api.removePrefs({key: name});
        }
    }
    //临时Storage引擎
    _app.sessionStorage = {
        getItem: function(name){
            return api.getGlobalData({key: name});
        },
        setItem: function(name, value){
            return api.setGlobalData({key: name,value: value});
        }
    }
    //自定义存储位置的文件 Storage引擎 构造函数
    _app.fileStorage = function(dir){
        if(!(this instanceof _app.fileStorage)) return new _app.fileStorage(dir);
        dir = dir || 'cache://';
        this.getItem = function(name){
            var path = dir+'/'+name+'.json';
            return api.readFile({sync: true,path: path});
        }
        this.setItem = function(name, value){
            var path = dir+'/'+name+'.json';
            return api.writeFile({data: value,path: path});
        }
    }
    _app.ajaxData = function(values, files){
        values = s94.type(values)=='Object' ? values : {};
        files = s94.type(files)=='Object' ? files : {};
        return {
            values: values,
            files: files
        }
    }
    /**
     * app专属eval方法
     * @param {JSString} jsstr 执行的js代码，和eval方法类似
     * @param {String} name 代码执行的窗口name，不传为当前窗口，初始窗口为"root"，支持使用点二级参数指定Frame，如："root.menu"
     */
    _app.eval = function(jsstr, name){
        var setup={};
        if(name && name.indexOf('.')!=-1){
            name = name.split('.');
            setup={name: name[0],frameName:name[1],script: jsstr};
        }else{
            setup={name: name,script: jsstr};
        }
        api.execScript(setup);
    }
    _app.win = function(name, op){
        //第二参数传入否表示关闭window
        if (op===false) {
            return api.closeWin(name ? {name:name} : {});
        } else {
            op = (typeof(op)=="object") ? op : {};
            var setup={};
            if(name.indexOf('http')===0){
                setup.name = s94.encode(name);
                setup.url = name;
                setup.reload = true;//网页默认刷新
            }else{
                if(name.indexOf('?')>0){
                    var arr = name.split('?');
                    name = arr[0];
                    setup.pageParam = s94.param_decode(arr[1]);
                    if (op.pageParam) {
                        setup.pageParam = s94.merge(setup.pageParam, op.pageParam);
                        delete op.pageParam;
                    }
                }
                setup.url = 'widget://html/'+name+'.html';
                setup.name = name;
            }
            api.openWin(s94.merge(setup,op));
        }
    }
    _app.frame = function(name, op){
        //第二参数传入否表示关闭frame
        if (op===false) {
            return api.closeFrame(name ? {name:name} : {});
        } else {
            op = (typeof(op)=="object") ? op : {};
            var setup={};
            if(name.indexOf('http')===0){
                setup.name = s94.encode(name);
                setup.url = name;
                setup.reload = true;//网页默认刷新
            }else{
                if(name.indexOf('?')>0){
                    var arr = name.split('?');
                    name = arr[0];
                    setup.pageParam = s94.param_decode(arr[1]);
                    if (op.pageParam) {
                        setup.pageParam = s94.merge(setup.pageParam, op.pageParam);
                        delete op.pageParam;
                    }
                }
                setup.url = 'widget://html/'+name+'.html';
                setup.name = name;
            }
            api.openFrame(s94.merge(setup,op));
        }
    }
    /**
     * 申请指定的权限
     * @param {Array} list 权限名数组，详情参考：https://developer.yonyou.com/docs/Client-API/API#hasPermission
     * @param {*} callback
     * @returns
     */
    _app.permission = function(list, callback){
        var req=[];
        api.hasPermission({list: list}).forEach(row => {
            if(!row.granted) req.push(row.name);
        });
        if(!req.length) return callback([]);

        api.requestPermission({list: req}, function(ret){
            var no_granted = [];
            ret.list.forEach(row => {
                if(!row.granted) no_granted.push(row.name)
            });
            callback(no_granted)
        })
    }
    /**
     * 窗口重新显示时刷新或者执行回调函数
     * @param {Object} callback
     */
    _app.show_reload = function(callback){
        if(typeof(callback) != 'function') return;
        var hidden = false;
        api.addEventListener({name: 'viewappear'}, function(ret, err){
            hidden && callback();
        });
        api.addEventListener({name: 'viewdisappear'}, function(ret, err){hidden = true;});
    }

    return _app;
})(typeof globalThis !== 'undefined' ? globalThis :
    typeof self !== "undefined" ? self :
        typeof window !== "undefined" ? window :
            typeof global !== "undefined" ? global : {})

export default s94_app;